/* * Copyright (C) 2013 YIXIA.COM * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.vov.vitamio; import android.content.Context; import com.yixia.vitamio.library.R; import com.yixia.zi.utils.CPU; import com.yixia.zi.utils.ContextUtils; import com.yixia.zi.utils.IOUtils; import com.yixia.zi.utils.Log; import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Inspect this class before using any other Vitamio classes. * <p/> * Don't modify this class, or the full Vitamio library may be broken. */ public class Vitamio { private static final String[] LIBS_CODECS = {"libffmpeg.so", "libOMX.9.so", "libOMX.11.so", "libOMX.14.so", "libOMX.16.so"}; private static final String[] LIBS_PLAYER = {"libvplayer.so"}; private static final String[] LIBS_SCANNER = {"libvscanner.so"}; private static final String[] LIBS_AV = {"libvao.0.so", "libvvo.0.so", "libvvo.7.so", "libvvo.8.so", "libvvo.9.so", "libvvo.j.so"}; private static final String LIBS_LOCK = ".lock"; private static final int VITAMIO_NOT_SUPPORTED = -1; private static final int VITAMIO_ARMV6 = 60; private static final int VITAMIO_ARMV6_VFP = 61; private static final int VITAMIO_ARMV7_VFPV3 = 70; private static final int VITAMIO_ARMV7_NEON = 71; private static final int vitamioType; static { int cpu = CPU.getFeature(); if ((cpu & CPU.FEATURE_ARM_NEON) > 0) vitamioType = VITAMIO_ARMV7_NEON; else if ((cpu & CPU.FEATURE_ARM_VFPV3) > 0 && (cpu & CPU.FEATURE_ARM_V7A) > 0) vitamioType = VITAMIO_ARMV7_VFPV3; else if ((cpu & CPU.FEATURE_ARM_VFP) > 0 && (cpu & CPU.FEATURE_ARM_V6) > 0) vitamioType = VITAMIO_ARMV6_VFP; else if ((cpu & CPU.FEATURE_ARM_V6) > 0) vitamioType = VITAMIO_ARMV6; else vitamioType = VITAMIO_NOT_SUPPORTED; } private static String vitamioPackage; private static String vitamioLibraryPath; /** * Call this method before using any other Vitamio specific classes. * <p/> * This method will use {@link #isInitialized(Context)} to check if Vitamio is * initialized at this device, and initialize it if not initialized. * * @param ctx Android Context * @return true if the Vitamio initialized successfully. */ public static boolean initialize(Context ctx) { return isInitialized(ctx) || extractLibs(ctx, R.raw.libarm); } /** * Same as {@link #initialize(Context)} * * @param ctx Android Context * @param rawId R.raw.libarm * @return true if the Vitamio initialized successfully. */ public static boolean initialize(Context ctx, int rawId) { return isInitialized(ctx) || extractLibs(ctx, rawId); } /** * Check if Vitamio is initialized at this device * * @param ctx Android Context * @return true if the Vitamio has been initialized. */ public static boolean isInitialized(Context ctx) { vitamioPackage = ctx.getPackageName(); vitamioLibraryPath = ContextUtils.getDataDir(ctx) + "libs/"; File dir = new File(getLibraryPath()); if (dir.exists() && dir.isDirectory()) { String[] libs = dir.list(); if (libs != null) { Arrays.sort(libs); for (String L : getRequiredLibs()) { if (Arrays.binarySearch(libs, L) < 0) { Log.e("Native libs %s not exists!", L); return false; } } File lock = new File(getLibraryPath() + LIBS_LOCK); FileReader fr = null; try { fr = new FileReader(lock); int appVersion = ContextUtils.getVersionCode(ctx); int libVersion = fr.read(); Log.i("isNativeLibsInited, APP VERSION: %d, Vitamio Library version: %d", appVersion, libVersion); if (libVersion == appVersion) return true; } catch (IOException e) { Log.e("isNativeLibsInited", e); } finally { IOUtils.closeSilently(fr); } } } return false; } public static String getVitamioPackage() { return vitamioPackage; } public static int getVitamioType() { return vitamioType; } public static final String getLibraryPath() { return vitamioLibraryPath; } private static final List<String> getRequiredLibs() { List<String> libs = new ArrayList<String>(); for (String[] libArray : new String[][]{LIBS_CODECS, LIBS_PLAYER, LIBS_SCANNER, LIBS_AV}) { for (String lib : libArray) libs.add(lib); } libs.add(LIBS_LOCK); return libs; } private static boolean extractLibs(Context ctx, int rawID) { long begin = System.currentTimeMillis(); final int version = ContextUtils.getVersionCode(ctx); Log.d("loadLibs start " + version); File lock = new File(getLibraryPath() + LIBS_LOCK); if (lock.exists()) lock.delete(); String libPath = copyCompressedLib(ctx, rawID, "libarm.so"); Log.d("copyCompressedLib time: " + (System.currentTimeMillis() - begin) / 1000.0); boolean inited = native_initializeLibs(libPath, getLibraryPath(), String.valueOf(Vitamio.getVitamioType())); new File(libPath).delete(); FileWriter fw = null; try { lock.createNewFile(); fw = new FileWriter(lock); fw.write(version); return true; } catch (IOException e) { Log.e("Error creating lock file", e); } finally { Log.d("initializeNativeLibs: " + inited); Log.d("loadLibs time: " + (System.currentTimeMillis() - begin) / 1000.0); IOUtils.closeSilently(fw); } return false; } private static String copyCompressedLib(Context ctx, int rawID, String destName) { byte[] buffer = new byte[1024]; InputStream is = null; BufferedInputStream bis = null; FileOutputStream fos = null; String destPath = null; try { try { String destDir = getLibraryPath(); destPath = destDir + destName; File f = new File(destDir); if (f.exists() && !f.isDirectory()) f.delete(); if (!f.exists()) f.mkdirs(); f = new File(destPath); if (f.exists() && !f.isFile()) f.delete(); if (!f.exists()) f.createNewFile(); } catch (Exception fe) { Log.e("loadLib", fe); } is = ctx.getResources().openRawResource(rawID); bis = new BufferedInputStream(is); fos = new FileOutputStream(destPath); while (bis.read(buffer) != -1) { fos.write(buffer); } } catch (Exception e) { Log.e("loadLib", e); return null; } finally { IOUtils.closeSilently(fos); IOUtils.closeSilently(bis); IOUtils.closeSilently(is); } return destPath; } static { System.loadLibrary("vinit"); } private native static boolean native_initializeLibs(String libPath, String destDir, String prefix); }